﻿#ifndef __GAF_CONTROLACTION_H__
#define __GAF_CONTROLACTION_H__

namespace GAF
{
	class ControlMap;
	//class Player
		//class Animation -* Runnable
			//class Action
				class ControlAction;
}
typedef GAF::ControlMap			GAF_CControlMap;
typedef GAF::ControlAction		GAF_CControlAction;

#include "GAF_Action.h"

#define GAF_CTRLMAP_LEFT		0
#define GAF_CTRLMAP_RIGHT		100
#define GAF_CTRLMAP_COUNT		(GAF_CTRLMAP_RIGHT - GAF_CTRLMAP_LEFT + 1)
#define GAF_CTRLMAP_ZERO		0.0f

namespace GAF
{
	typedef _MAP<UINT, double>	MarkMap;

	/// 控制图类
	class ControlMap
	{
	public:
		ControlMap();
		ControlMap(const ControlMap& amScr);
		~ControlMap();

		/// 相对调整
		void			Adjust(double dValue);
		/// 添加调整标记
		void			AddMark(UINT nID, double dValue);
		/// 移除调整标记
		void			RemoveMark(UINT nID);

		const double*		Values();

		void			operator=(const ControlMap& amOther);

	private:
		void			CopyOther(const ControlMap& amOther);
		void			Switch(UINT nID, UINT& nPrevID, UINT& nNextID);
		void			Transition(UINT nLeftID, double nLeftValue,
						UINT nRightID, double dRightValue);
		void			NewValues();

	public:
		double*			m_pdValues;
		int			m_nCtrlCount;		// 控制点数量

	private:
		MarkMap			m_mapMarks;
	};

	// 控制成员基类
	class CtrlItemBase
	{
	public:
		CtrlItemBase();

		virtual double		GetAttrib() = 0;
		virtual	void		SetAttrib(double dAttrib) = 0;

	public:
		ControlMap		m_cmControl;
		GAF_DTimeTicks		m_ttRun;		// 单轮运行时间
		int			m_nTimes;		// 运行次数
		ActionMode		m_amMode;		// 运行模式
		GAF_DTimeTicks		m_ttOneCtrl;		// 每一控制点所需时间
	public:
		bool			m_isStop;		// 是否结束
		int			m_nWay;			// 方向
		int			m_nCurCtrl;		// 当前控制点
		int			m_nCurTimes;		// 当前运行次数
		GAF_DTimeTicks		m_ttExcess;		// 多余的时间
	};

	// 控制成员类
	template<class T>
	class CtrlItem : public CtrlItemBase
	{
	public:
		CtrlItem(T& tAttrib);

		double			GetAttrib();
		void			SetAttrib(double dAttrib);

	private:
		T&			m_tAttrib;
	};

	template<class T>
	CtrlItem<T>::CtrlItem(T& tAttrib) :
		m_tAttrib(tAttrib)
	{
	}

	template<class T>
	double CtrlItem<T>::GetAttrib()
	{
		return (double)m_tAttrib;
	}

	template<class T>
	void CtrlItem<T>::SetAttrib(double dAttrib)
	{
		m_tAttrib = (T)dAttrib;
	}

	typedef _MAP<_STRING, CtrlItemBase*>
					CtrlItemMap;
	/// 控制动作类
	class ControlAction : public Action
	{
	public:
		ControlAction();
		~ControlAction();

	public:
		template<class T>
		void			AddControl(
					_STRING		strName,
					T&		tAttrib,
					ControlMap	cm,
					GAF_DTimeTicks	ttRun,
					int		nTimes,
					ActionMode	amMode
					);

	protected:
		bool			OnPlay(Bundle* pParam);
		bool			OnUpdate(TimeTicks ttUsed);
		bool			OnStop();

	private:
		void			UpdateAttrib(TimeTicks ttUsed, CtrlItemBase* pItem);
		void			ChangeAttrib(CtrlItemBase* pItem, int nCurCtrl, int nNextCtrl);

	private:
		CtrlItemMap		m_mapControls;

	};

	template<class T>
	void ControlAction::AddControl(
		_STRING		strName,
		T&		tAttrib,
		ControlMap	cm,
		GAF_DTimeTicks	ttRun,
		int		nTimes,
		ActionMode	amMode
		)
	{
		CtrlItem<T>* _pciNew	= new CtrlItem<T>(tAttrib); //GAF_NEW_PRM(CtrlItem<T>, (tAttrib));
		_pciNew->m_cmControl	= cm;
		_pciNew->m_ttRun	= ttRun;
		_pciNew->m_nTimes	= nTimes;
		_pciNew->m_amMode	= amMode;
		_pciNew->m_ttOneCtrl	= ttRun / (cm.m_nCtrlCount - 1);

		m_mapControls.insert(CtrlItemMap::value_type(strName, _pciNew));
	}

}

#endif